package com.plian.system.service.fr.yearindicators.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.plian.Tools.TokenUtil;
import com.plian.Tools.UuidUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.dao.fr.financeindicators.FinanceIndicatorsDao;
import com.plian.system.dao.fr.fstdvalue.FstdvalueDao;
import com.plian.system.dao.fr.groupyearindicatorsvalue.GroupYearIndicatorsValueDao;
import com.plian.system.dao.fr.indicatorsstdvalue.IndicatorsStdvalueDao;
import com.plian.system.dao.fr.yearindicators.YearIndicatorsDao;
import com.plian.system.dao.fr.yearindicatorsvalue.YearIndicatorsValueDao;
import com.plian.system.entity.fr.indicators.YearIndicators;
import com.plian.system.mapper.fr.indicators.YearIndicatorsMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.page.Page;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.service.fr.yearindicators.IYearGroupIndicatorsValueService;
import com.plian.system.service.fr.yearindicators.IYearIndicatorsService;
import com.plian.system.service.fr.yearindicators.IYearIndicatorsValueService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.user.ISysUserService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.service.yth.IYearlyDebtService;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.plian.system.constant.sys.FormStatusConstant.*;
import static com.plian.system.constant.sys.FormTypeConstant.FR_YEARINDICATORS;

/**
 * 说明：企业年度指标录入
 */
@Service
@Transactional
public class YearIndicatorsServiceImpl extends ServiceImpl<YearIndicatorsMapper, YearIndicators> implements IYearIndicatorsService, BaseFlowService {
    @Autowired
    YearIndicatorsDao yearindicatorsDao;
    @Autowired
    YearIndicatorsValueDao yearindicatorsvalueDao;
    @Autowired
    GroupYearIndicatorsValueDao groupyearindicatorsvalueDao;
    @Autowired
    FileService fileService;
    @Autowired
    FormWorkflowService formWorkflowService;
    @Autowired
    FinanceIndicatorsDao financeindicatorsDao;
    @Autowired
    IndicatorsStdvalueDao indicatorsstdvalueDao;
    @Autowired
    FstdvalueDao fstdvalueDao;
    @Autowired
    IFormCodeService formCodeService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IOrgService orgService;

    @Autowired
    private IYearlyDebtService yearlyDebtService;

    @Autowired
    private IYearGroupIndicatorsValueService groupIndicatorsValueService;

    @Autowired
    private IYearIndicatorsValueService indicatorsValueService;


    private static final Logger LOGGER = LoggerFactory.getLogger(YearIndicatorsServiceImpl.class);

    /**
     * 保存
     *
     * @param pd
     * @return
     */
    @Override
    public ObjResult save(PageData pd) {
        try {
            pd.put("orgId", TokenUtil.getTokenOrgId());
            PageData pe = yearindicatorsDao.findbyorg(pd);
            if (pe != null && pe.getString("id") != null) {
                ObjResult objResult = new ObjResult(CommonCode.EXIST);
                objResult.setMessage("该年度已有单据");
                return objResult;
            }
            String id = UuidUtil.get32UUID();
            pd.put("id", id);
            pd.put("code", formCodeService.getCode(FormTypeConstant.FR_YEARINDICATORS));
            pd.put("status", "0");
            pd.put("createTime", new Date());
            pd.put("updateTime", new Date());
            pd.put("createUser", TokenUtil.getTokenUserId());
            pd.put("updateUser", TokenUtil.getTokenUserId());
            pd.put("formType", FormTypeConstant.FR_YEARINDICATORS);
            yearindicatorsDao.save(pd);
            ObjectMapper mapper = new ObjectMapper();
            //保存从表: 年度指标从表
            List<PageData> list_YearIndicatorsValue = mapper.convertValue((List<PageData>) pd.get("listYearIndicatorsValue"), new TypeReference<List<PageData>>() {
            });
            saveYearIndicatorsValue(list_YearIndicatorsValue, id);
            List<PageData> list_GroupYearIndicatorsValue = mapper.convertValue((List<PageData>) pd.get("listGroupYearIndicatorsValue"), new TypeReference<List<PageData>>() {
            });
            saveGroupYearIndicatorsValue(list_GroupYearIndicatorsValue, id);
            //保存附件
            fileService.saveAll(id, (List<HashMap>) pd.get("list_doc"));
            HashMap<String, Object> processVariable = new HashMap<>();
            formWorkflowService.startProcessAndSimulate(id, pd.getString("formType"), processVariable);
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 修改
     *
     * @param pd
     * @return
     */
    @Override
    public ObjResult edit(PageData pd) {
        try {
            PageData pe = yearindicatorsDao.findbyorg(pd);
            if (pe != null && pe.getString("id") != null && !pe.getString("id").equals(pd.getString("id"))) {
                ObjResult objResult = new ObjResult(CommonCode.EXIST);
                objResult.setMessage("该年度已有单据");
                return objResult;
            }
            String id = pd.getString("id");
            pd.put("updateTime", new Date());
            pd.put("updateUser", TokenUtil.getTokenUserId());
            yearindicatorsDao.edit(pd);
            ObjectMapper mapper = new ObjectMapper();
            //修改从表: 年度指标从表
            List<PageData> list_YearIndicatorsValue = mapper.convertValue((List<PageData>) pd.get("listYearIndicatorsValue"), new TypeReference<List<PageData>>() {
            });
            List<PageData> list_GroupYearIndicatorsValue = mapper.convertValue((List<PageData>) pd.get("listGroupYearIndicatorsValue"), new TypeReference<List<PageData>>() {
            });
            yearindicatorsvalueDao.delPrenteId(id);
            saveYearIndicatorsValue(list_YearIndicatorsValue, id);
            groupyearindicatorsvalueDao.delPrenteId(id);
            saveGroupYearIndicatorsValue(list_GroupYearIndicatorsValue, id);
            //修改附件
            fileService.edit(id, (List<HashMap>) pd.get("list_doc"));
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 查询列表
     *
     * @return
     */
    @Override
    public ListResult listPage(PageData pd) {
        ListResult listResult;
        try {
            pd.put("orgId", TokenUtil.getTokenOrgId());
            boolean isPage = true;
            if (pd.containsKey("isPage")) {
                isPage = (boolean) pd.get("isPage");
            }
            Page page = new Page(isPage, pd);
            List<PageData> list = yearindicatorsDao.listPage(page);
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(list);
            listResult.setTotal(page.getTotal());
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }

    /**
     * 查询列表
     *
     * @return
     */
    @Override
    public ListResult listReport(PageData pd) {
        ListResult listResult;
        try {
            pd.put("orgId", TokenUtil.getTokenOrgId());
            boolean isPage = true;
            pd.put("status", FINISH);
            if (pd.containsKey("isPage")) {
                isPage = (boolean) pd.get("isPage");
            }
            Page page = new Page(isPage, pd);
            List<PageData> list = yearindicatorsDao.listPage(page);
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(list);
            listResult.setTotal(page.getTotal());
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }

    /**
     * 根据id查询
     *
     * @param pd
     * @return
     */
    @Override
    public ObjResult findbyid(PageData pd) {
        ObjResult objResult;
        String id = pd.getString("id");
        try {
            PageData p = yearindicatorsDao.findbyid(id);
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(p);
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
            return objResult;
        }
    }

    @Override
    public ObjResult del_ids(List<String> ids) {
        try {
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            yearindicatorsDao.del_ids(ids);
            for (String s : ids) {
                formWorkflowService.deleteProcessInstance(s);
            }
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 保存
     *
     * @param list    从表列表
     * @param prentId 主键id
     */
    private void saveYearIndicatorsValue(List<PageData> list, String prentId) throws Exception {
        if (list != null && list.size() > 0) {
            for (PageData pageData : list) {
                pageData.put("yearIndicatorsId", prentId);
                pageData.put("id", UuidUtil.get32UUID());
            }
            yearindicatorsvalueDao.saveAll(list);
        }
    }

    /**
     * 保存
     *
     * @param list    从表列表
     * @param prentId 主键id
     */
    private void saveGroupYearIndicatorsValue(List<PageData> list, String prentId) throws Exception {
        if (list != null && list.size() > 0) {
            for (PageData pageData : list) {
                pageData.put("yearIndicatorsId", prentId);
                pageData.put("id", UuidUtil.get32UUID());
            }
            groupyearindicatorsvalueDao.saveAll(list);
        }
    }

    /**
     * 查询主表，从表数据
     *
     * @param pd
     * @return
     */
    @Override
    public ObjResult findidAll(PageData pd) {
        String id = pd.getString("id");
        ObjResult objResult;
        try {
            //主表信息
            PageData p = yearindicatorsDao.findbyid(id);
            List<PageData> list_YearIndicatorsValue = yearindicatorsvalueDao.find_parentId(id);
            p.put("listYearIndicatorsValue", list_YearIndicatorsValue);
            List<PageData> list_GroupYearIndicatorsValue = groupyearindicatorsvalueDao.find_parentId(id);
            p.put("listGroupYearIndicatorsValue", list_GroupYearIndicatorsValue);
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(p);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
        }
        return objResult;
    }

    /**
     * 提交单据
     *
     * @param formId 单据id
     */
    @Override
    public HashMap<String, Object> commit(String formId) {
        PageData pageData = new PageData();
        pageData.put("status", String.valueOf(FLOW));
        ArrayList<String> ids = new ArrayList<>();
        ids.add(formId);
        pageData.put("id", ids);
        try {
            yearindicatorsDao.refer(pageData);
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException("上报失败");
        }
        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String, Object>();
    }

    /**
     * 退回单据
     *
     * @param formId 单据id
     */
    @Override
    public Boolean reject(String formId, int formState, String comment) {
        PageData pageData = new PageData();
        pageData.put("status", String.valueOf(formState));
        pageData.put("id", Collections.singletonList(formId));
        try {
            yearindicatorsDao.refer(pageData);
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException("回退失败");
        }
        return true;
    }

    /**
     * 单据完成后
     *
     * @param formId
     */
    @Override
    public Boolean finish(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(FINISH));
            pageData.put("id", Collections.singletonList(formId));
            yearindicatorsDao.refer(pageData);
            pageData.put("ids", Collections.singletonList(formId));
            List<PageData> lp = yearindicatorsDao.findByIds(pageData); //获取刚审批通过的年度录入单据
            for (PageData p : lp) {
                PageData pi = new PageData();
                pi.put("orgId", p.getString("orgId"));
                pi.put("groupId", p.getString("groupId"));
                pi.put("createTime", new Date());
                pi.put("updateTime", new Date());
                pi.put("createUser", p.getString("createUser"));
                pi.put("updateUser", p.getString("updateUser"));
                pi.put("fyear", p.getString("fyear"));
                pi.put("fmonth", "0");
                List<PageData> py = yearindicatorsvalueDao.find_parentId(p.getString("id"));//获取年度录入的监管线和预警线
                for (PageData ps : py) {
                    PageData pf = new PageData();
                    pf.put("id", UuidUtil.get32UUID());
                    pf.putAll(pi);
                    PageData pv = financeindicatorsDao.findbyname(ps.getString("indicatorsName"));//通过名字查找预警指标
                    pf.put("indicatorsId", pv.getString("id"));
                    pf.put("fname", pv.getString("name"));
                    pf.put("isGroup", "0");
                    indicatorsstdvalueDao.save(pf);
                    List<PageData> lpi = new ArrayList<PageData>();
                    PageData pse = new PageData();
                    pse.put("id", UuidUtil.get32UUID());
                    pse.put("indicatorsStdvalueId", pf.getString("id"));
                    pse.put("standardValues", ps.getString("warningLine"));
                    pse.put("valueName", "较低值");
                    PageData pse2 = new PageData();
                    pse2.put("id", UuidUtil.get32UUID());
                    pse2.put("indicatorsStdvalueId", pf.getString("id"));
                    pse2.put("standardValues", ps.getString("regulatoryLine"));
                    pse2.put("valueName", "较差值");
                    PageData pse3 = new PageData();
                    pse3.put("id", UuidUtil.get32UUID());
                    pse3.put("indicatorsStdvalueId", pf.getString("id"));
                    pse3.put("standardValues", ps.getString("average"));
                    pse3.put("valueName", "平均值");
                    lpi.add(pse);
                    lpi.add(pse2);
                    lpi.add(pse3);
                    fstdvalueDao.saveAll(lpi);
                }
                List<PageData> py1 = groupyearindicatorsvalueDao.find_parentId(p.getString("id"));//获取年度录入的监管线和预警线
                if (py1 != null && py1.size() > 0) {
                    for (PageData ps : py1) {
                        PageData pf = new PageData();
                        pf.put("id", UuidUtil.get32UUID());
                        pf.putAll(pi);
                        PageData pv = financeindicatorsDao.findbyname(ps.getString("indicatorsName"));//通过名字查找预警指标
                        pf.put("indicatorsId", pv.getString("id"));
                        pf.put("fname", pv.getString("name"));
                        pf.put("isGroup", "1");
                        indicatorsstdvalueDao.save(pf);
                        List<PageData> lpi = new ArrayList<PageData>();
                        PageData pse = new PageData();
                        pse.put("id", UuidUtil.get32UUID());
                        pse.put("indicatorsStdvalueId", pf.getString("id"));
                        pse.put("standardValues", ps.getString("warningLine"));
                        pse.put("valueName", "较低值");
                        PageData pse2 = new PageData();
                        pse2.put("id", UuidUtil.get32UUID());
                        pse2.put("indicatorsStdvalueId", pf.getString("id"));
                        pse2.put("standardValues", ps.getString("regulatoryLine"));
                        pse2.put("valueName", "较差值");
                        PageData pse3 = new PageData();
                        pse3.put("id", UuidUtil.get32UUID());
                        pse3.put("indicatorsStdvalueId", pf.getString("id"));
                        pse3.put("standardValues", ps.getString("average"));
                        pse3.put("valueName", "平均值");
                        lpi.add(pse);
                        lpi.add(pse2);
                        lpi.add(pse3);
                        fstdvalueDao.saveAll(lpi);
                    }
                }


            }

        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("单据流转完成时修改单据状态失败！"));
        }
        return true;
    }

    /**
     * @param formIds 单据ids
     */
    @Override
    public List<PageData> findByIds(List<String> formIds) {
        try {
            PageData pageData = new PageData();
            pageData.put("ids", formIds);
            List<PageData> byIds = yearindicatorsDao.findByIds(pageData);
            List<PageData> pageData1 = new ArrayList<>();
            for (PageData pd : byIds) {
                String unitname = pd.getString("UNITNAME");
                pd.put("orgName", unitname);
                pageData1.add(pd);
            }
            //UNITNAME
            return pageData1;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("根据单据id列表查询报表失败！"));
        }
    }

    @Override
    public List<Integer> getFormType() {
        return Arrays.asList(FR_YEARINDICATORS);
    }

    @Override
    public void goBackToStash(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(UNREVIEWED));
            pageData.put("id", Collections.singletonList(formId));
            yearindicatorsDao.refer(pageData);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
        }
    }

}